// require base class
Flair.require('Flair/Db/Adapter.js');
 
/**
 * Class for performing common operations on an sqlConnection asynchronously
 */
Flair.Db.Async = Flair.extend(Flair.Db.Adapter, function (connection) {
	
	/**
	 * On result event handler does some internal clean up an forwards to user specified onResult handler
	 */
	this.onResult = function(event, data) {
		// apply fetch<x> filter to result data
		var results = this[ data.filter ]( event.target.getResult() );
		// send results to user supplied callback
		if(data.onResult)
			// provide result set & statement reference
			data.onResult( results, event.target );
	}
	
	this.onError = function (event, data) {
		// call user defined 
		if(data.onError)
			data.onError(event);		
	}
	
	/**
	 * Run an sql query.
	 * Optionally run asynch by passing a responder 
	 *
	 * @param string sql
	 * @param array params
	 * @param Responder resp
	 */
	this.query = function (sql, params, onResult, onError, resultFilter) { 
		var statement = new air.SQLStatement();
		statement.sqlConnection = this.connection;

		// call back maker because we want our callback to have access to some options
		var cb = function (scope, options) { return function (event) { scope.onResult(event, options); }; }
		
		statement.addEventListener(air.SQLEvent.RESULT, cb(this, {'filter': resultFilter, 'onResult': onResult})); 
		statement.addEventListener(air.SQLErrorEvent.ERROR, cb(this, {'onError': onError})); 
		
		statement.text = sql;
		
		if(params)
			for (var i in params)
				statement.parameters[i] = params[i];
		
		statement.execute();
			
		return statement;
	};

	/**
	 * Run sql query and fetch all returned records
	 *
	 * @param string sql
	 * @param array params
	 */
	this.fetchAll = function (sql, params, onResult, onError) { 
		var stmt = this.query( sql, params, onResult, onError, '_fetchAll' );
		return stmt;
	};
	
	this.fetchRow = function (sql, params, onResult, onError) { 
		var stmt = this.query( sql, params, onResult, onError, '_fetchRow' );
		return stmt;
	};
	this.fetchCol = function (sql, params, onResult, onError) { 
		var stmt = this.query( sql, params, onResult, onError, '_fetchCol' );
		return stmt;
	};
	this.fetchOne = function (sql, params, onResult, onError) { 
		var stmt = this.query( sql, params, onResult, onError, '_fetchOne' );
		return stmt;
	};
});